<?php

namespace App\Http\Controllers\Api;

use App\Models\User;
use App\Models\UserAuth;
use App\Models\Oauth;
use Exception;
use Log;
use Illuminate\Http\Request;
use Socialite;
use GuzzleHttp\Client;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Illuminate\Support\Facades\Redis;

class WechatAppUtils
{
    protected $client = null;

    protected $config = [];

    public function __construct()
    {
        $this->config = [
            'wechat_app' => [
                'appid'  => env('WECHAT_APPID'),    //审核通过的APPID
                'secret' => env('WECHAT_SECRET'),   //应用APP SECRET 详情见上图
            ],
            'time_out'   => 5,
        ];
        $this->client = new Client([
            'time_out' => $this->config['time_out'],
        ]);
    }

    /**
     * 获取微信用户access_token
     *
     * @param [String] $code
     * @return Array
     */
    public function accessToken($code)
    {
        $accessTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token';

        $response = $this->client->request('GET', $accessTokenUrl, [
            'query' => [
                'grant_type' => 'authorization_code',
                'code'       => $code,
                'appid'      => Arr::get($this->config, 'wechat_app.appid'),
                'secret'     => Arr::get($this->config, 'wechat_app.secret'),
            ],
        ]);

        $result = $response->getbody()->getContents();

        return empty($result) ? null : json_decode($result, true);
    }

    public function only_accessToken()
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/token';

        $response = $this->client->request('GET', $url, [
            'query' => [
                'grant_type' => 'client_credential',
                'appid'      => Arr::get($this->config, 'wechat_app.appid'),
                'secret'     => Arr::get($this->config, 'wechat_app.secret'),
            ],
        ]);

        $result = $response->getbody()->getContents();

        return empty($result) ? null : json_decode($result, true);
    }

    /**
     * 微信用户信息
     *
     * @param [String] $accessToken
     * @param [String] $openId
     * @return Array
     */
    public function userInfo($accessToken, $openId)
    {
        $userInfoUrl = 'https://api.weixin.qq.com/sns/userinfo';

        $response = $this->client->request('GET', $userInfoUrl, [
            'query' => [
                'access_token' => $accessToken,
                'openid'       => $openId,
                'lang'         => 'zh_CN',
            ],
        ]);

        $result = $response->getbody()->getContents();

        return empty($result) ? null : json_decode($result, true);
    }
}


class WechatController extends Controller
{
    /**
     * 微信授权登录，
     * 第一次授权插入数据，并查询是否绑定用户id
     */
    public function wechat(Request $request) {
        $utils = new WechatAppUtils;
        $code = $request->code;
        //获取微信token
        $accessTokenData = $utils->accessToken($code);

        // $code 错误或者过期
        if (!Arr::has($accessTokenData, ['access_token', 'openid'])) {
            return $this->failed('参数已经失效，请重新点击授权!', 200);
        }

        $openid = $accessTokenData['openid'];
        $access_token = $accessTokenData['access_token'];
        // 第一次授权
        // 获取用户信息
        $userInfo = $utils->userInfo($access_token, $openid);
        $OauthData = [
            'oauth_type' => 'wechat',
            'oauth_id' => $openid,
            'info' => json_encode($userInfo)
        ];
        $oauth = Oauth::updateOrCreate(['oauth_id' => $openid], $OauthData);
        // 未绑定手机号
        if (!$oauth['user_id']) {
            return $this->success(['info' => $userInfo, 'unBindPhone' => true]);
        }

        // 已经绑定手机号
        $user = User::find($oauth['user_id']);
        $user->update([
            'name' => $userInfo['nickname'],
            'avatar_url' => $userInfo['headimgurl'],
        ]);
        $oauthIdentifier = [
            'user_id' => $user->id,
            'identity_type' => 'oauth',
            'identifier' => $user->phone,
            'password' => bcrypt(str_random(16))
        ];
        UserAuth::updateOrCreate([
            'user_id' => $user->id,
            'identity_type' => 'oauth',
            'identifier' => $user->phone
        ], $oauthIdentifier);

        $UserController = new UserController();

        return $UserController->createToken($oauthIdentifier['identifier'], $oauthIdentifier['password'], 'oauth', '微信授权登录失败！');
    }

    /**
     * 消息推送
    */
    // 获取jsapi_ticket
    // public function getJSapi_ticket() {
    // }


    /**
     * 获取微信基础接口凭证Access_token
     * @param $refresh 强制刷新， 默认false
     * @return String
     */
    public function getAccess_token() {
        $access_token = Redis::get('access_token');
        if ($access_token) {
            return $access_token;
        }
        $utils = new WechatAppUtils;
        $data = $utils->only_accessToken();
        if ($data['access_token']) {
            $access_token = $data['access_token'];
            Redis::setex('access_token', 7100, $access_token);
            return $access_token;
        }
        return $this->failed('获取access_token失败！', 200);
    }

    //发送模板消息
    public function send_template_message($data) {
        $client = new client();
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $this->getAccess_token();
        
        $response = $client->request('POST', $url, [
            'json' => $data,
        ]);
        $result = $response->getbody()->getContents();

        return empty($result) ? null : json_decode($result, true);
    }

    // 支付消息模板通知
    public function send($order, $station) {
        $oauth = Oauth::where('user_id', $order->user_id)->first();
        $openId = $oauth->oauth_id;
        
        $json = array(
            'touser' => $openId, // openid是发送消息的基础
            'template_id' => 'ww7WuRZWsWE7goaO-P71Wr8nB5D7oahZq0o6NN-GxG4', // 模板id
            'url' => config('app.frontEndUrl').'orderdetail/'.$order->order_id, // 点击跳转地址
            'topcolor' => '#FF0000', // 顶部颜色
            'data' => array(
                'first' => array('value' => '请在指定油站核销使用'),
                'keyword1' => array('value' => $station->title),
                'keyword2' => array('value' => $order->order_id),
                'keyword3' => array('value' => '柴油'),
                'keyword4' => array('value' => ($order->order_amount / 100).'元', 'color' => '#f44336'),
                'keyword5' => array('value' => $order->payment_time),
                'remark' => array('value' => '请在48小时内使用！'),
            )
        );

        return $this->send_template_message($json);
    }
    
    // 核销消息模板通知
    public function check($order, $station) {
        $oauth = Oauth::where('user_id', $order->user_id)->first();
        $openId = $oauth->oauth_id;
        
        $json = array(
            'touser' => $openId, // openid是发送消息的基础
            'template_id' => 'oLd9Gwq8AO-8LkgBhZPMAzDL8IiJK8r9t_NF0B9dr8s', // 模板id
            'url' => config('app.frontEndUrl').'orderdetail/'.$order->order_id, // 点击跳转地址
            'topcolor' => '#FF0000', // 顶部颜色
            'data' => array(
                'first' => array('value' => '加油卡核销成功！'),
                'keyword1' => array('value' => $order->order_id),
                'keyword2' => array('value' => '一键加油'.($order->order_amount / 100).'元'),
                'keyword3' => array('value' => $station->title),
                'keyword4' => array('value' => $order->check_time),
                'remark' => array('value' => '感谢您的使用！'),
            )
        );

        return $this->send_template_message($json);
    }
}
